from django.utils.deprecation import MiddlewareMixin
from django_redis import get_redis_connection
from django.http import JsonResponse, HttpRequest
import re, hmac, base64, json, time


class JwtAuthMiddleware(MiddlewareMixin):

    def process_request(self, request: HttpRequest):
        if re.search(r'(csrf|login|admin|wallpaper)', request.path_info):
            return
        token = request.headers.get("JSONWebToken")
        userID = request.headers.get("userID")
        if not token or not userID:
            return JsonResponse({'code': 405, 'msg': '缺失请求参数'})
        try:
            payload = JwtAuthMiddleware.parser(token.encode())
        except Exception:
            return JsonResponse({'code': 0, 'msg': 'Token验证失败'})
        redis_conn = get_redis_connection()
        redis_token = redis_conn.get(userID)
        if not redis_token or redis_token.decode() != token:
            return JsonResponse({'code': -1, 'msg': 'Token已过期或该账号被另一台设备登录'})
        if int(time.time()) > int(payload["exp"]):
            return JsonResponse({'code': -2, 'msg': 'Token已过期'})
        return

    @staticmethod
    def parser(token):
        header_bs, payload_bs, signature_bs = token.split(b".")

        payload_js = JwtAuthMiddleware.b64decode(payload_bs)  # 解码为json
        payload = json.loads(payload_js)  # 解码为字典
        payload.update({"username": '_'.join(payload['username'].split('_')[:-2])})

        return payload  # 返回自定义内容

    @staticmethod
    def b64encode(js):
        return base64.urlsafe_b64encode(js).replace(b"=", b"")

    @staticmethod
    def b64decode(bs):
        # 加回来等号
        rem = len(bs) % 4  # 取余
        if rem > 0:
            bs += b'=' * (4 - rem)

        return base64.urlsafe_b64decode(bs)
